package com.test1.administrator.website;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;

import com.test1.administrator.website.dao.DBOperator;
import com.test1.administrator.website.entity.Website;
import com.test1.administrator.website.util.websiteIsNullException;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2017/5/20.
 */

public class NetService extends Service {

    private int port=6259;
//    客户端集合
    private List<Socket> mClientList=new ArrayList<Socket>();
//    服务器
    private ServerSocket mserver=null;
//    线程池对象
    private ExecutorService mExecutors=null;
//    客户端
    public static final int ADDWEBSITE=11;

//    public static final int REFRESH=22;
    DBOperator dbOperator;


     Handler curHandler;

    public  void addWebsite(Website website){
//      add and refresh
        dbOperator=new DBOperator(NetService.this);
        dbOperator.insert(website.getName(),website.getSite());
    }

//    public void refresh(){
//
//    }



    /**
     * Called by the system when the service is first created.  Do not call this method directly.
     */
    @Override
    public void onCreate() {
        super.onCreate();
        Log.v("service","create");



//                将客户端添加到list中
                new Thread(){
                    @Override
                    public void run() {
                        try {
                            mserver=new ServerSocket(port);
//            创建线程池
                            mExecutors= Executors.newCachedThreadPool();
                            Socket client=null;
//            死循环到等待多个客户端连接，连接一个创建一个线程进行管理
                            while (true){
                                Log.v("service","=====================a new client");
                        client=mserver.accept();
                                mClientList.add(client);
//                启动一个线程用以守候从客户端发来的消息
                                mExecutors.execute(new Service(client));
                            }

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }.start();

        curHandler=new Handler(
                new Handler.Callback() {
                    @Override
                    public boolean handleMessage(Message msg) {
                        switch (msg.what){
                            case ADDWEBSITE:addWebsite((Website)msg.obj);
                                break;
                        }
                        return false;
                    }
                }
        );

    }




    /**
     * Called by the system to notify a Service that it is no longer used and is being removed.  The
     * service should clean up any resources it holds (threads, registered
     * receivers, etc) at this point.  Upon return, there will be no more calls
     * in to this Service object and it is effectively dead.  Do not call this method directly.
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    /**
     * Return the communication channel to the service.  May return null if
     * clients can not bind to the service.  The returned
     * {@link IBinder} is usually for a complex interface
     * that has been <a href="{@docRoot}guide/components/aidl.html">described using
     * aidl</a>.
     * <p>
     * <p><em>Note that unlike other application components, calls on to the
     * IBinder interface returned here may not happen on the main thread
     * of the process</em>.  More information about the main thread can be found in
     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
     * Threads</a>.</p>
     *
     * @param intent The Intent that was used to bind to this service,
     *               as given to {@link Context#bindService
     *               Context.bindService}.  Note that any extras that were included with
     *               the Intent at that point will <em>not</em> be seen here.
     * @return Return an IBinder through which clients can call on to the
     * service.
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    class Service implements Runnable {
        private Socket socket;
        private BufferedReader in=null;
        private PrintWriter out=null;
        private String message="";

        public Service(Socket socket){
            this.socket=socket;
            try {
                in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));

                message="服务器地址："+socket.getInetAddress();
                this.sendMessage(message);
                message="客户端总数："+mClientList.size();
                this.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see Thread#run()
         */
        @Override
        public void run() {
            while (true){
//                Log.v("server","======================server运行中");
//                如果发来信息为exit 关闭连接

                try {

                    if(in.ready()) {
//                        Log.v("message", "============未接收到" + message);
//                        Log.v("message", "============未接收到" +in.readLine());
                        message = in.readLine();
//                        if(message==null)continue;
//                        Log.v("message", "============null" + message);
//                        Log.v("message", "============接收到" + message);
                        if (message != null) {
                            if (message.equals("exit")) {
                                closeSocket();
                                break;
                            } else {
//                            处理message信息
                                if(message.matches("SendWebSite#.*")){
                                    Log.e("message", message);
                                    Log.v("server", "收到了！！！！！！！！！！！" + message);
//                                    此为客户端向服务端发送网址
                                    try {
                                        String temp="";
                                        temp=message.replaceFirst("SendWebSite#","");

                                        String name=temp.split("####")[0];
                                        String site="";
                                        if(temp.split("####").length==2){
                                            site=temp.split("####")[1];
                                        }

                                        Website myWebsite=new Website(name,site);
                                        Message msgNet=Message.obtain();
                                        msgNet.what=ADDWEBSITE;
                                        msgNet.obj=myWebsite;
                                        curHandler.sendMessage(msgNet);

                                    } catch (websiteIsNullException e) {
                                        e.printStackTrace();
                                    }

                                }

                            }

                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        public void sendMessage(String message){
//            获取输出流
            message=message+"\n";
                out.print(message);
        }

        public void closeSocket(){
            mClientList.remove(socket);
            try {
                in.close();
                message="主机："+socket.getInetAddress()+"关闭连接";
                socket.close();
                this.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



}
